import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  # 隐藏 INFO 和 WARNING 日志

import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error,r2_score

# --------------------- 数据读取 ---------------------
data = pd.read_csv("E:/GraduateDesign/LinearUse.csv")
X = data.drop(columns=['rrr']).values
y = data['rrr'].values.reshape(-1, 1)

# --------------------- 数据标准化 ---------------------
scaler_X = StandardScaler()
scaler_y = StandardScaler()
X_scaled = scaler_X.fit_transform(X)
y_scaled = scaler_y.fit_transform(y)

# --------------------- 适配 LSTM 输入格式 ---------------------
X_reshaped = X_scaled.reshape(-1, 1, X_scaled.shape[1])

# --------------------- 划分训练集和测试集 ---------------------
X_train, X_test, y_train, y_test = train_test_split(
    X_reshaped, y_scaled, test_size=0.2, random_state=42, shuffle=True
)

# --------------------- 构建 LSTM 模型 ---------------------
model = tf.keras.Sequential([
    tf.keras.layers.LSTM(64, input_shape=(X_train.shape[1], X_train.shape[2])),
    tf.keras.layers.Dense(1)
])

model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss='mse',
    metrics=['mae']
)

# --------------------- 训练模型 ---------------------
history = model.fit(
    X_train, y_train,
    epochs=500,
    batch_size=32,
    validation_split=0.2,
    verbose=1
)

# --------------------- 绘制损失曲线 ---------------------
plt.figure(figsize=(10, 6))
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss Progression')
plt.xlabel('Epochs')
plt.ylabel('Loss (MSE)')
plt.legend()
plt.show()

# --------------------- 预测和评估 ---------------------
y_pred_scaled = model.predict(X_test)

# 反标准化还原真实尺度
y_pred = scaler_y.inverse_transform(y_pred_scaled)
y_test_original = scaler_y.inverse_transform(y_test)

# 确保为一维数组
y_test_flat = y_test_original.ravel()
y_pred_flat = y_pred.ravel()

# 计算评估指标
rmse = mean_squared_error(y_test_flat, y_pred_flat, squared=False)
mae = mean_absolute_error(y_test_flat, y_pred_flat)
mape = np.mean(np.abs((y_test_flat - y_pred_flat) / y_test_flat)) * 100
r2 = r2_score(y_test_flat, y_pred_flat)

print(f"RMSE: {rmse:.4f}")
print(f"MAE: {mae:.4f}")
print(f"MAPE: {mape:.2f}%")
print(f"R²: {r2:.4f}")